local skynet = require "skynet"
local netpack = require "skynet.netpack"
local socketdriver = require "skynet.socket"
local websocket = require "http.websocket"

local log = require "sky_log"

local gateserver = {}

local socket	-- listen socket
local queue		-- message queue
local maxclient	-- max client
local client_number = 0
local CMD = setmetatable({}, { __gc = function() netpack.clear(queue) end })
local nodelay = false

local connection = {}
-- true : connected
-- nil : closed
-- false : close read

function gateserver.start(handler)
	function CMD.handle_connect(fd, addr)
		if client_number >= maxclient then
			socketdriver.shutdown(fd)
			return
		end
		connection[fd] = true
		client_number = client_number + 1
		handler.connect(fd, addr)
	end

	function CMD.closeclient(watchdog, fd)
		if fd ~= socket then
			client_number = client_number - 1
			if connection[fd] then
				--connection[fd] = false	-- close read
				connection[fd] = nil
			end
		else
			socket = nil
		end
	end

	function CMD.query_tables()
		log.info("gateserver query_tables connection= ", connection)
		log.info("client_number=", client_number)
		handler.query_tables()
	end

	function CMD.open( source, conf )
		assert(not socket)
		local address = conf.address or "0.0.0.0"
		local port = assert(conf.port)
		maxclient = conf.maxclient or 1024
		nodelay = conf.nodelay
		log.info(string.format("Listen on %s:%d", address, port))
		socket = socketdriver.listen(address, port)
		socketdriver.start(socket, CMD.handle_connect)
		if handler.open then
			return handler.open(source, conf)
		end
	end

	function CMD.close()
		assert(socket)
		socketdriver.close(socket)
	end

	local function init()
		skynet.dispatch("lua", function (_, address, cmd, ...)
			local f = CMD[cmd]
			if f then
				skynet.ret(skynet.pack(f(address, ...)))
			else
				skynet.ret(skynet.pack(handler.command(cmd, address, ...)))
			end
		end)
	end

	--log.info("websocket=", websocket)
	skynet.start(init)
end

return gateserver
